/*
 * fat.h
 *
 *  Created on: 18/09/2011
 *      Author: utn_so
 */

#ifndef FAT_H_
#define FAT_H_
#define _XOPEN_SOURCE 600
#include "interfaz.h"
#include "fat_defs.h"
//#include "utils.h"
#include <fcntl.h>
#include <unistd.h>
#include "archivo.h"
#include <fuse.h>



#define BYTESPERSEC 512
#define SECPERBLOQ 2
#define BYTESFATCACHE 4096

#ifndef DEF_BYTE
#define DEF_BYTE
	typedef unsigned char BYTE;
#endif

#ifndef DEF_UINT16
#define DEF_UINT16
	typedef unsigned short UINT16;
#endif

#ifndef DEF_UINT32
#define DEF_UINT32
	typedef unsigned long UINT32;
#endif

#define FAT_HTONS(n) ((((unsigned short)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8))
#define FAT_HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
				((((unsigned long)(n) & 0xFF00)) << 8) | \
				((((unsigned long)(n) & 0xFF0000)) >> 8) | \
				((((unsigned long)(n) & 0xFF000000)) >> 24))

#define GET_32BIT_WORD(buffer, location)	( ((int32_t)buffer[location+3]<<24) + ((int32_t)buffer[location+2]<<16) + ((int32_t)buffer[location+1]<<8) + (int32_t)buffer[location+0] )
#define GET_16BIT_WORD(buffer, location)	( ((UINT16)buffer[location+1]<<8) + (UINT16)buffer[location+0] )

#define SET_32BIT_WORD(buffer, location, value)	{ buffer[location+0] = (BYTE)((value)&0xFF); \
												  buffer[location+1] = (BYTE)((value>>8)&0xFF); \
												  buffer[location+2] = (BYTE)((value>>16)&0xFF); \
												  buffer[location+3] = (BYTE)((value>>24)&0xFF); }

#define SET_16BIT_WORD(buffer, location, value)	{ buffer[location+0] = (BYTE)((value)&0xFF); \
												  buffer[location+1] = (BYTE)((value>>8)&0xFF); }

int32_t fat_load (int32_t numBloqueFat);
int32_t fat_flush ();
unsigned char *leerFatRegion();
unsigned char *leerClusterDataRegion(int32_t numCluster);
unsigned char *leerClusterDataRegionArchivo(ARCHIVO *arch, int32_t numCluster);
int32_t escribirArchivo(char *pathArchivo, char *datos);
struct nodoLFN *listarDirectorioDataRegion(int32_t numCluster);
int32_t buscarEnDirectorio(struct fat_dir_entry *entry, int32_t numClusterDirectorio, char *nombreBuscado, int32_t *numeroBytesEntradaCluster);
void borrarEspacios(char *ch, int32_t longitud);
void strrev(char* str);
char * convertirMayusculas( char * pszCadena );

int32_t EscribirEntradaFatRegion(int32_t numCluster, char *contenido);

int32_t EscribirClusterDataRegion(int32_t numCluster, unsigned char *contenido);
int32_t leerClusterFATRegion(int32_t numCluster);
int32_t f_getattr(const char *path, struct stat *stbuf);
unsigned char *leerArchivo(ARCHIVO *arch, size_t tamanioArchivo,  off_t offset);
int32_t obtenerClusterInicial(char *pathArchivo);
struct fat_dir_entry *obtenerEntradaDataRegion(char *pathArchivo, int32_t *clusterDirectorio, int32_t *numeroBytesEntradaCluster);
int32_t truncarArchivo(char *pathArchivo, int32_t tamanioNuevo, int32_t *clusterInicial);
void eliminarEntradaDataRegion(unsigned char *cluster, int32_t numEntrada);
int32_t renombrarArchivo(char *pathInicial, char *nuevoNombre);
struct cluster *listaClustersEncadenados(int32_t primerCluster, int32_t *cantidadClusters);
int32_t obtenerClusterLibre();
int32_t *agregarClusterACadena(int32_t primerCluster);
int32_t *eliminarClusterDeCadena(int32_t primerCluster);
int32_t obtenerCantidadClustersLibres();
int32_t obtenerDireccionCluster(int32_t numCluster);
int32_t load_bootsector();
struct cluster *nuevoNodoCluster();
struct cluster *creaColaCluster(struct cluster *ult, int32_t x);
struct nodoLFN *nuevoNodoLFN();
struct nodoLFN *creaColaLFN(struct nodoLFN *ult, char *nombre);
int32_t crearArchivo(char *pathArchivo);
int32_t crearDirectorio(char *path);
int32_t modificarArchivo(ARCHIVO *arch, char *datos, int32_t offset, size_t size);
int32_t borrarArchivo(char *path);
int32_t borrarDirectorio(char *path);

void fsinfo();
void listarClusters(struct cluster *listaClusters, int32_t cantidadClusters);
void finfo(char *path);
char *cadenaClusters(struct cluster *listaClusters, int32_t cantidadClusters);


struct fatCache
{
	int32_t numBloqueFat;
	int32_t clusterComienzo;
	int32_t modificado;
	unsigned char data[BYTESFATCACHE];
};


struct cluster
{
	int32_t numCluster;
	struct cluster *sgt;
};

struct nodoLFN
{
	char nombre[14];
	struct nodoLFN *sgt;
};

#endif /* FAT_H_ */
